package task

import (
	g "gogame/game"
	cfg "gogame/game/manage/config/structs"
	"gogame/game/manage/module"
	"gogame/game/module/base"
	"gogame/gameservice/worker"
	"gogame/lib"
	"gogame/module_option/taskoption"
	"gogame/pb"
)

var taskStypeMap = make(map[int32]*BaseTask)

type ModuleTask struct {
	*base.ModuleBase
	Api
}

var Task *ModuleTask

func init() {
	Task = &ModuleTask{
		ModuleBase: base.NewModuleBase(),
	}

	_moduleName := "task"
	// 路由注册 未定义Api2Func默认采用反射筛选符合条件的方法注册和调用
	worker.Register(_moduleName, Task)
	// 模块注册
	module.Manage.Task = Task

}

// GetTaskNVal 获取任务nval
func (m *ModuleTask) GetTaskNVal(uid string, taskCon *cfg.GameTaskData) int32 {
	_taskClass := taskStypeMap[taskCon.Stype]
	if _taskClass == nil {
		return 0
	}

	return _taskClass.GetInitVal(uid, taskCon)
}

// FmtTaskData 格式化任务数据
func (m *ModuleTask) FmtTaskData(taskId int32, option taskoption.FmtTaskData) *pb.ModelTask {
	_taskCon := option.TaskCon
	if _taskCon == nil {
		_taskCon = g.GC.Task().Get(taskId)
	}

	_initTaskData := &pb.ModelTask{
		SType:  _taskCon.Stype,
		Type:   _taskCon.Type,
		TaskId: taskId,
		NVal:   option.NVal,
		Finish: 0,
	}
	if option.Uid != "" {
		_nt := g.C.Now()
		_initTaskData.NVal = m.GetTaskNVal(option.Uid, _taskCon)
		_initTaskData.Uid = option.Uid
		_initTaskData.Id = g.C.GetObjectId()
		_initTaskData.ReTime = _nt
		_initTaskData.Ctime = _nt
	}

	return _initTaskData

}

// SetTaskVal 设置任务数据
func (m *ModuleTask) SetTaskVal(uid string, sType int32, val int32, chkVal any, IsInc bool) {
	_taskClass := taskStypeMap[sType]
	// 该任务类型未定义
	if _taskClass == nil {
		return
	}

	_unFinishTaskList := g.DATA.Task.GetUnFinishByStype(uid, sType)
	// 没有需要处理的任务
	if _unFinishTaskList == nil {
		return
	}

	var (
		_overTypeList     []int32
		_objectId2SetData = make(map[string]map[string]any)
	)
	for _, task := range _unFinishTaskList {
		_taskId := task.TaskId
		_taskCon := g.GC.Task().Get(_taskId)
		// 任务不存在
		if _taskCon == nil {
			continue
		}

		_pVal := _taskCon.Pval
		_nVal := task.NVal
		// 已满足任务需求
		if _nVal >= _pVal {
			continue
		}

		// 不符合任务要求
		if !_taskClass.FuncChkCall(_taskCon.Cond, chkVal) {
			continue
		}

		_resVal := _nVal
		// 累加
		if IsInc {
			_resVal += val

		} else {
			// 覆盖
			if val <= _nVal {
				continue
			}
			_resVal = val
		}

		// 不可超过任务所需总值
		if _resVal > _pVal {
			_resVal = _pVal
		}

		_objectId2SetData[task.Id] = map[string]any{
			"nval": _resVal,
		}
		// 任务可完成
		if _resVal >= _pVal {
			if !lib.InSliceInt32(task.Type, _overTypeList) {
				_overTypeList = append(_overTypeList, task.Type)
			}
		}

	}

	// 设置任务数据
	for objectId, setData := range _objectId2SetData {
		g.DATA.Task.Set(uid, objectId, setData)
	}

}
